/**
 * 
 */
package com.xnkf.common.util;

import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;

/**
 * @ClassName: TokenUtils
 * @Description: TODO
 * @author xaoyaoyao
 * @date 2017年7月23日 下午1:01:43
 */
public abstract class TokenUtils {
	/**
	 * @Fields TIME : TODO
	 */
	public static final String TIME = "time";

	/**
	 * @Fields USER_ID : TODO
	 */
	public static final String USER_ID = "userId";

	private static final SecureRandom numberGenerator = new SecureRandom();

	public static String generateUUIDToken(boolean upperCase) {
		String token = StringUtils.remove(UUID.randomUUID().toString(), '-');
		return upperCase ? token.toUpperCase() : token;
	}

	public static String generateAuthcToken(int userId, boolean upperCase) {
		String uid = Long.toHexString(userId).toLowerCase();
		byte[] randomBytes = new byte[8];
		numberGenerator.nextBytes(randomBytes);
		String random = Long.toHexString(System.currentTimeMillis());
		int len = random.length();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < uid.length(); i++) {
			char ch = uid.charAt(i);
			char c = random.charAt(i % len);
			sb.append((char) (ch ^ c));
		}
		uid = Hex.encodeHexString(sb.toString().getBytes(Charset.forName("UTF8")));
		String length = Integer.toHexString(len);
		String token = length + random + uid;
		return upperCase ? token.toUpperCase() : token;
	}

	public static Map<String, Object> decodeAuthcToken(String token) {
		if (token == null || token.length() <= 1) {
			return null;
		}
		token = token.toLowerCase();
		char cc = token.charAt(0);
		int l = Integer.parseInt(cc + "", 16);

		try {
			String key = token.substring(1, 1 + l);
			if (key.length() != l) {
				return null;
			}
			String str = token.substring(1 + l);
			if (str == null) {
				return null;
			}
			byte[] uid = Hex.decodeHex(str.toCharArray());
			int len = key.length();
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < uid.length; i++) {
				byte ch = uid[i];
				char c = key.charAt(i % len);
				sb.append((char) (ch ^ c));
			}
			long userId = Long.parseLong(sb.toString(), 16);
			Map<String, Object> rs = new HashMap<String, Object>();
			rs.put(USER_ID, userId);
			rs.put(TIME, Long.parseLong(key, 16));
			return rs;
		} catch (Exception e) {
			return null;
		}
	}

	public static void main(String[] args) throws Exception {
		System.out.println(System.currentTimeMillis());
		String token = TokenUtils.generateAuthcToken(9, true);
		System.out.println(token);
		System.out.println(TokenUtils.decodeAuthcToken(token));
	}
}
